package com.wyc.apidriver.service.impl;

import com.wyc.apidriver.feign.DriverUserFeignClient;
import com.wyc.apidriver.feign.VerificationCodeFeignClient;
import com.wyc.apidriver.service.VerificationCodeService;
import com.wyc.internalCommon.constant.CommonStatusEnum;
import com.wyc.internalCommon.constant.IdentityContant;
import com.wyc.internalCommon.constant.TokenContant;
import com.wyc.internalCommon.request.DriverUserDTO;
import com.wyc.internalCommon.request.VerificationCodeDTO;
import com.wyc.internalCommon.response.NumberCodeResponse;
import com.wyc.internalCommon.response.TokenResponse;
import com.wyc.internalCommon.result.ApiResult;
import com.wyc.internalCommon.util.JWTUtils;
import com.wyc.internalCommon.util.RedisKeyUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;

import java.util.concurrent.TimeUnit;

@Service
public class VerificationCodeServiceImpl implements VerificationCodeService {

    @Autowired
    private StringRedisTemplate stringRedisTemplate;

    @Autowired
    private DriverUserFeignClient driverUserFeignClient;

    @Autowired
    private VerificationCodeFeignClient verificationCodeFeignClient;

    /**
     * 司机获取验证码
     * @param verificationCodeDTO
     * @return
     */
    @Override
    public ApiResult sendVerificationCode(VerificationCodeDTO verificationCodeDTO) {
        // 根据司机手机号查询，是否存在该司机用户
        if (null == verificationCodeDTO.getDriverPhone()){
            return ApiResult.error(CommonStatusEnum.DRIVER_USER_NULL.getCode(),CommonStatusEnum.DRIVER_USER_NULL.getMsg());
        }
        String driverPhone = verificationCodeDTO.getDriverPhone();
        ApiResult resultDriver = driverUserFeignClient.query(driverPhone);

        if (null == resultDriver.getData()){
            return ApiResult.error(CommonStatusEnum.DRIVER_USER_NOT_EXISTS.getCode(),CommonStatusEnum.DRIVER_USER_NOT_EXISTS.getMsg());
        }

        // 获取验证码
        ApiResult<NumberCodeResponse> resultNumCode = verificationCodeFeignClient.getNumberCode(6);
        NumberCodeResponse data = resultNumCode.getData();
        // 验证码
        int verificationCode = data.getNumberCode();

        // 调用第三方发送验证码

        // redis存储验证码
        stringRedisTemplate.opsForValue().set(RedisKeyUtils.generatorCodeKeyByPhone(driverPhone, IdentityContant.DRIVER_IDENTITY),
                String.valueOf(verificationCode),2, TimeUnit.MINUTES);

        return ApiResult.success(verificationCode);
    }

    /**
     * 司机校验验证码
     * @param verificationCodeDTO
     * @return
     */
    @Override
    public ApiResult checkVerificationCode(VerificationCodeDTO verificationCodeDTO) {

        // redis获取验证码
        String driverPhone = verificationCodeDTO.getDriverPhone();
        String verificationCode = verificationCodeDTO.getVerificationCode();
        String driverKey = RedisKeyUtils.generatorCodeKeyByPhone(driverPhone, IdentityContant.DRIVER_IDENTITY);
        String redisVerificationCode = stringRedisTemplate.opsForValue().get(driverKey);
        // 校验验证码是否正确
        if (null == redisVerificationCode || !redisVerificationCode.equals(verificationCode)){
            // 验证码失效
            return ApiResult.error(CommonStatusEnum.VERIFICATION_CODE_ERROR.getCode(),CommonStatusEnum.VERIFICATION_CODE_ERROR.getMsg());
        }

        // 颁发双token
        String successToken = JWTUtils.generatorToken(driverPhone,IdentityContant.DRIVER_IDENTITY, TokenContant.SUCCESS_TOKEN_TYPE);
        String refreshToken = JWTUtils.generatorToken(driverPhone,IdentityContant.DRIVER_IDENTITY,TokenContant.REFRESH_TOKEN_TYPE);
        String successTokenKey = RedisKeyUtils.generatorTokenKeyByPhoneWithId(driverPhone, IdentityContant.DRIVER_IDENTITY, TokenContant.SUCCESS_TOKEN_TYPE);
        String refreshTokenKey = RedisKeyUtils.generatorTokenKeyByPhoneWithId(driverPhone, IdentityContant.DRIVER_IDENTITY, TokenContant.REFRESH_TOKEN_TYPE);

        stringRedisTemplate.opsForValue().set(successTokenKey,successToken,2,TimeUnit.HOURS);
        stringRedisTemplate.opsForValue().set(refreshTokenKey,refreshToken,3,TimeUnit.HOURS);

        TokenResponse tokenResponse = new TokenResponse();
        tokenResponse.setAccessToken(successToken);
        tokenResponse.setRefreshToken(refreshToken);

        return ApiResult.success(tokenResponse);
    }
}
